package com.szcinda.service.dto.log;

import com.szcinda.repository.*;
import com.szcinda.service.SnowFlakeFactory;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.criteria.Predicate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

@Service
@Transactional
public class ExportLogServiceImpl implements ExportLogService {
    private final ExportLogRepository exportLogRepository;
    private final SnowFlakeFactory snowFlakeFactory;
    private final ZadOrderRepository zadOrderRepository;
    private final GhOrderRepository ghOrderRepository;

    public ExportLogServiceImpl(ExportLogRepository exportLogRepository, ZadOrderRepository zadOrderRepository, GhOrderRepository ghOrderRepository) {
        this.exportLogRepository = exportLogRepository;
        this.zadOrderRepository = zadOrderRepository;
        this.ghOrderRepository = ghOrderRepository;
        this.snowFlakeFactory = SnowFlakeFactory.getInstance();
    }

    @Override
    public void create(ExportLog exportLog) {
        exportLog.setId(snowFlakeFactory.nextId("EL"));
        exportLogRepository.save(exportLog);
    }

    @Override
    public void update(ExportLog log) {
        ExportLog exportLog = exportLogRepository.findFirstById(log.getId());
        exportLog.setRemark(log.getRemark());
        exportLogRepository.save(exportLog);
        String ids = exportLog.getIds();
        if (ids != null) {
            String[] idsArray = ids.split(",");
            List<ZadOrder> zadOrders = zadOrderRepository.findAll(Arrays.asList(idsArray));
            for (ZadOrder zadOrder : zadOrders) {
                zadOrder.setBillRemark(log.getRemark());
            }
            zadOrderRepository.save(zadOrders);
            List<GhOrder> ghOrders = ghOrderRepository.findAll(Arrays.asList(idsArray));
            for (GhOrder ghOrder : ghOrders) {
                ghOrder.setBillRemark(log.getRemark());
            }
            ghOrderRepository.save(ghOrders);
        }
    }

    @Override
    public List<ExportLog> findByUser(String tableName, String type, String userId) {
        Specification<ExportLog> specification = ((root, criteriaQuery, criteriaBuilder) -> {
            List<Predicate> predicates = new ArrayList<>();
            Predicate tableNameEq = criteriaBuilder.equal(root.get("tableName").as(String.class), tableName);
            predicates.add(tableNameEq);
            Predicate typeEq = criteriaBuilder.equal(root.get("type").as(String.class), type);
            predicates.add(typeEq);
            Predicate userIdEq = criteriaBuilder.equal(root.get("userId").as(String.class), userId);
            predicates.add(userIdEq);
            return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
        });
        Sort order = new Sort(Sort.Direction.DESC, "id");
        Pageable pageable = new PageRequest(0, 20, order);
        return exportLogRepository.findAll(specification, pageable).getContent();
    }
}
